#include "register_and_login.h"
#include"cJSON.h"
#include"Upload_database.h"
#include"cyclic_reception.h"
#include"sys_log.h"
#include"heart_beat.h"
// 定义互斥锁，确保更新和检查心跳时间时不会产生竞态条件
pthread_mutex_t heartbeat_lock;


// 记录客户端信息的数组
struct client_info clients[10];


int main(int argc,const char* argv[])
{
    log_init();
    int sock = 0;
    int listenfd = 0;
    int ret = 0;
    char buf[MAX_SIZE] = {0};
    char *dest;

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        LOG_E("sock");
        perror("sock");
        exit(-1);
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr(IP);

    ret = bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if (ret == -1) {
        LOG_E("bind");
        perror("bind");
        exit(-1);
    }

    listen(sock, 5);

    struct epoll_event ev;
    struct epoll_event events[MAX_EVENTS];

    int conn_sock, nfds, epollfd;

    epollfd = epoll_create1(0);

    if (epollfd == -1) {
        LOG_E("epoll_create1\n");
        perror("epoll_create1");
        exit(EXIT_FAILURE);
    }

    ev.events = EPOLLIN; // 设置读就绪事件
    ev.data.fd = sock;   // 关联监听套接字

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1) {
        LOG_E("epoll_ctl: listen_sock\n");
        perror("epoll_ctl: listen_sock");
        exit(EXIT_FAILURE);
    }



    // 创建心跳包线程
    pthread_t tid;
    init_client_info();
    pthread_create(&tid, NULL, send_heartbeat, &epollfd);




    while (1) {
        int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            LOG_E("epoll_wait\n");
            perror("epoll_wait");
            exit(EXIT_FAILURE);
        }

        for (int n = 0; n < nfds; n++) {
            if (events[n].data.fd == sock) {// 有新连接请求
                listenfd = accept(sock, NULL, NULL);
                if (listenfd == -1) {
                    LOG_E("accept\n");
                    perror("accept");
                    exit(EXIT_FAILURE);
                }
                ev.events = EPOLLIN;
                ev.data.fd = listenfd;
                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev) == -1) {
                    LOG_E("epoll_ctl: listenfd\n");
                    perror("epoll_ctl: listenfd");
                    exit(EXIT_FAILURE);
                }

                pthread_mutex_lock(&heartbeat_lock); // 加锁，防止竞态条件
                for (int j = 0; j < 10; j++) {
                    if (clients[j].fd == -1) {
                        clients[j].fd = listenfd;
                        clients[j].last_heartbeat = time(NULL); // 初始化心跳时间
                        break;
                    }
                }
                pthread_mutex_unlock(&heartbeat_lock); // 解锁


            }
            else {//是通信套接字
                memset(buf, 0, sizeof(buf));
                ret = recv(events[n].data.fd, buf, MAX_SIZE, 0);
                if (ret <= 0) {
                    printf("recv failed or connection closed\n");
                    close(events[n].data.fd);
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, events[n].data.fd, NULL);
                    continue;
                }
                printf("在main函数的recv-------message: %s\n", buf);
                LOG_I("在main函数的recv-------message： %s\n", buf);
                if (strcmp(buf, "fd1") == 0) {
                    int fd1 = events[n].data.fd;
                    
                    handle_client_message(listenfd, buf); // 正常处理消息并更新心跳时间

                    register_and_login_recv(fd1);
                    // 从 epoll 中移除这个文件描述符，以避免 epoll 处理它
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, events[n].data.fd, NULL);
                }
                else if (strcmp(buf, "fd2") == 0) {
                    pthread_t tid;
                    int* client_fd = malloc(sizeof(int));
                    *client_fd = events[n].data.fd;
                    LOG_D("线程中使用的是：%d\n", *client_fd);


                    ret = pthread_create(&tid, NULL, cyclic_reception, client_fd);
                    if (ret != 0) {
                        LOG_E("pthread_create\n");
                        perror("pthread_create");
                        free(client_fd);
                        exit(-1);
                    }
                    LOG_I("线程创建成功\n");
                    printf("Thread created successfully\n");

                    // 从 epoll 中移除这个文件描述符，以避免 epoll 处理它
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, events[n].data.fd, NULL);
                }
            }
        }
    }
    log_destroy();
    close(sock);
    close(epollfd);
    return 0;
}
